package com.mayfool.gitmanager.core.manager;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mayfool.gitmanager.core.helper.LogHelper;
import com.mayfool.gitmanager.core.entity.CredentialsInfo;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 凭证管理器
 * 
 * @author zhou.xu
 * @date 2024-01-08 10:30:00
 * 
 * 该类提供了Git仓库凭证管理的核心功能，包括：
 * 1. 凭证信息的存储和检索
 * 2. 凭证信息的持久化（JSON格式）
 * 3. URL解析和域名提取
 * 
 * 使用ConcurrentHashMap确保线程安全
 * 实现了单例模式，所有方法都是静态的
 * 凭证信息按照仓库的根域名进行存储
 */
public class CredentialsManager {

    /**
     * 凭证信息文件名
     */
    private static final String fileName = "credentials.json";

    /**
     * 凭证信息映射表，使用ConcurrentHashMap保证线程安全
     * key: 仓库根域名
     * value: 凭证信息对象
     */
    private static final ConcurrentMap<String, CredentialsInfo> credentialsInfos = new ConcurrentHashMap<>();

    /**
     * 获取指定URL对应的凭证信息
     * 会自动提取URL的根域名进行匹配
     * 
     * @param url Git仓库URL
     * @return 凭证信息对象，如果不存在则返回null
     */
    public static CredentialsInfo getCredentialsInfo(String url) {
        return credentialsInfos.get(getRootUrl(url));
    }

    /**
     * 设置指定URL的凭证信息
     * 会自动提取URL的根域名作为key
     * 设置后会自动保存到JSON文件
     * 
     * @param url Git仓库URL
     * @param credentialsInfo 凭证信息对象
     */
    public static void setCredentialsInfo(String url, CredentialsInfo credentialsInfo) {
        credentialsInfos.put(getRootUrl(url), credentialsInfo);
        saveToJson();
    }

    /**
     * 从URL中提取根域名
     * 例如：
     * https://github.com/user/repo.git -> github.com
     * git@gitlab.com:user/repo.git -> gitlab.com
     * 
     * @param url Git仓库URL
     * @return 根域名
     */
    private static String getRootUrl(String url) {
        // 获取url的域名
        String rootUrl = url;
        if (url.contains("://")) {
            rootUrl = url.substring(url.indexOf("://") + 3);
        }
        if (rootUrl.contains("/")) {
            rootUrl = rootUrl.substring(0, rootUrl.indexOf("/"));
        }
        return rootUrl;
    }

    /**
     * 将凭证信息保存为JSON文件
     * 使用Jackson库进行序列化
     * 文件保存在当前用户目录下的credentials.json
     */
    private static void saveToJson() {
        ObjectMapper mapper = new ObjectMapper();
        try {
            mapper.writeValue(new File(System.getProperty("user.dir"), fileName), credentialsInfos);
        } catch (IOException e) {
            LogHelper.getInstance().append("JSON保存失败: ").appendLine(e.getMessage());
        }
    }

    /**
     * 从JSON文件加载凭证信息
     * 在类加载时通过静态代码块调用
     * 如果文件不存在或加载失败，凭证映射表保持为空
     */
    private static void loadFromJson() {
        ObjectMapper mapper = new ObjectMapper();
        File jsonFile = new File(System.getProperty("user.dir"), fileName);
        if (jsonFile.exists()) {
            try {
                Map<String, CredentialsInfo> credentialsInfoMap = mapper.readValue(jsonFile, new TypeReference<>() {
                });
                credentialsInfos.putAll(credentialsInfoMap);
            } catch (IOException e) {
                LogHelper.getInstance().append("JSON加载失败: ").appendLine(e.getMessage());
            }
        }
    }

    /**
     * 静态初始化块
     * 在类加载时自动从JSON文件加载已保存的凭证信息
     */
    static {
        loadFromJson();
    }
}
